package com.yuanian.ecsplus.reflect;

import com.yuanian.businessobject.model.vo.base.BOAreaFieldSetupVO;
import com.yuanian.businessobject.model.vo.base.BOAreaSetupVO;
import com.yuanian.businessobject.model.vo.bodefine.BODefineSetupVO;
import com.yuanian.ecsplus.annotation.*;
import com.yuanian.ecsplus.exception.EcsPlusException;
import com.yuanian.ecsplus.page.PageFilter;
import com.yuanian.ecsplus.page.PageFilterParam;
import com.yuanian.ecsplus.platform.PlatformSupport;
import com.yuanian.ecsplus.platform.SpringContextBean;
import com.yuanian.ecsplus.utils.DateUtils;
import java.math.BigDecimal;
import java.util.*;

/**
 * 持久化metaclass
 * @param <T>
 */
public class SimplePersistenceMetaClass<T> extends SimpleMetaClass implements PersistenceMetaClass {

    //ECS平台对应的apiName
    protected String apiName;

    //需要持久化的字段
    protected List<EcsField> persistenceFields;

    //需要展示的字段
    protected List<EcsField> map2ObjectFields;

    //boMainId对应的字段
    protected EcsField idField;

    //平台的支撑类
    protected PlatformSupport platformSupport;

    protected Map<String, BOAreaFieldSetupVO> fieldSetupVOMap;

    public SimplePersistenceMetaClass(Class<T> clz) {
        super(clz);
        this.persistenceFields = new ArrayList<>();
        this.map2ObjectFields = new ArrayList<>();
        //获取类上的Entity注解
        this.platformSupport = SpringContextBean.getBean(PlatformSupport.class);
        BusinessObject businessObject = clz.getDeclaredAnnotation(BusinessObject.class);
        if (businessObject == null) {
            throw new EcsPlusException(clz + "实体类上不存在BusinessObject注解");
        }
        this.apiName = businessObject.apiName();
        //获取ECS平台业务对象的配置
        BODefineSetupVO boDefineSetupVO = this.platformSupport.getSetup(apiName);
        BOAreaSetupVO areaSetupVO = boDefineSetupVO.getAreas();
        List<BOAreaFieldSetupVO> fieldSetupVOList = areaSetupVO.getFields();
        fieldSetupVOMap = new HashMap<>();
        for (BOAreaFieldSetupVO boAreaFieldSetupVO : fieldSetupVOList) {
            fieldSetupVOMap.put(boAreaFieldSetupVO.getCode(), boAreaFieldSetupVO);
        }
        List<EcsField> allField = this.allField;
        //遍历字段
        for (EcsField field : allField) {
            if (field.isAnnotationPresent(Transient.class) || !fieldSetupVOMap.containsKey(field.getName())) {
                continue;
            }

            if (!field.isAnnotationPresent(ReadOnly.class)) {
                BOAreaFieldSetupVO boAreaFieldSetupVO = fieldSetupVOMap.get(field.getName());
                //非系统字段，加入可持久化
                //if (!boAreaFieldSetupVO.getIsSys()) {
                field.setBoAreaFieldSetupVO(boAreaFieldSetupVO);
                this.persistenceFields.add(field);
                //}
            }

            if (!field.isAnnotationPresent(Hidden.class)) {
                BOAreaFieldSetupVO boAreaFieldSetupVO = fieldSetupVOMap.get(field.getName());
                if (field.getBoAreaFieldSetupVO() == null) {
                    field.setBoAreaFieldSetupVO(boAreaFieldSetupVO);
                }
                map2ObjectFields.add(field);
            }

            if (field.isAnnotationPresent(Id.class) || field.getField().equals("objectId")) {
                BOAreaFieldSetupVO boAreaFieldSetupVO = fieldSetupVOMap.get("objectId");
                if (field.getBoAreaFieldSetupVO() == null) {
                    field.setBoAreaFieldSetupVO(boAreaFieldSetupVO);
                }
                idField = field;
            }
        }
    }

    public EcsField getIdField() {
        return this.idField;
    }

    public String getApiName() {
        return this.apiName;
    }

    @Override
    public String getSql(PageFilter pageFilter, String concatStr) {
        List<PageFilterParam> params = pageFilter.getParams();
        if (params == null || params.size() == 0) {
            return "";
        } else {
            String sql = "";
            PageFilterParam param = null;
            for (int i = 0; i < params.size(); i++) {
                param = params.get(i);
                if (i < params.size() - 1) {
                    sql = sql + param.getFieldName() + param.getOperate() + getSqlFragment(param.getFieldName(), param.getFieldValue()) + " " + concatStr + "  ";
                } else {
                    sql = sql + param.getFieldName() + param.getOperate() + getSqlFragment(param.getFieldName(), param.getFieldValue());
                }
            }
            return sql;
        }
    }

    public String getSqlFragment(String fieldName, String fieldValue) {
        Class clz = getFieldType(fieldName);
        if (clz == null) {
            throw new EcsPlusException("sql过滤在VO类中未找到字段");
        } else {
            if (clz == BigDecimal.class) {
                return fieldValue;
            } else if (clz == String.class) {
                return "'" + fieldValue + "'";
            } else if (clz == Date.class) {
                return DateUtils.strToDate(fieldValue);
            } else {
                return "";
            }
        }
    }

    @Override
    public List<EcsField> getObject2MapFields() {
        return this.persistenceFields;
    }

    @Override
    public List<EcsField> getMap2ObjectFields() {
        return this.map2ObjectFields;
    }

    /*public Map<Field, String> getRefMap() {
        return refMap;
    }*/
}
